#pragma once
#include<opencv2/opencv.hpp>
#include<queue>
#include<fstream>
#include<memory>
using namespace cv;
using namespace std;

#define DEBUG
#define DEBUG_FORC
#define QUEUE_NUM 250     //original 150
#define PI 3.14159265359

namespace  rm
{

struct Img_Time
{
    Mat srcImg;
    Mat roiImg;
    Rect roi;
    Mat roiImg_R;
    Rect roi_R;
    double time;
};

class Windmill
{
public:
    Windmill();
    ~Windmill();
    void loadImg(Mat frame_, double time);
//基本函数
    double Max(double a, double b, double c);           //calculate the max munber of the three numbers
    double Min(double a, double b, double c);           //calculate the min munber of the three numbers
    float distance(Point2f Pointa, Point2f Pointb);     //calculate distance of two points
    void refresh();
//参数预设
    void setClockwise(){ _isclockwise = 1; }            //设置转动方向
    void setAntiClockwise(){ _isclockwise = 0; }
    bool getDirection() { return _isclockwise; }        //获得转动方向
    void setColor(int i);                                 //设置颜色
    void setBuffType(int i){ buff_type = i;}            //设置大小符
//图像识别
    void readFile();
    void Fan_recognition(vector<Point> templateContour);
    void R_recognition(vector<Point> templateContour);
    void Detect();
//运动预测
    Point2f forecastNextPoint(Point2f pt1, Point2f pt2);
    Point2f returnNextPoint();
    Point2f getNextPoint();
    const vector<Point2f> getArmorInsideVertex() const;
    const RotatedRect getArmorInside() const;

    void show_omegas();
    bool Whether_To_Hit(vector<vector<Point>> contours);

    double fit_phi(vector<Point2d> points);

    bool getIsfund()
    {
        return _isfund;
    }
    Mat getImage()
    {
        return _srcImg.srcImg;
    }
    int _loopNumber = 0;

private:
//风车预设
    int colorNumber;                                    //风车颜色
//图片处理参数
    int MAXRANGE_SWATTER,MINRANGE_SWATTER;              //打击苍蝇拍轮廓的范围
    int MAXRANGE_R,MINRANGE_R;                          //打击R的轮廓的范围
    int MAXRANGE_FAN,MINRANGE_FAN;                      //打击扇叶的轮廓的范围
    int MAXRANGE_RECTANGE,MINRANGE_RECTANGE;            //打击矩形轮廓的范围（矩形是在完成整个击打过程中出现的）
    float OFFSET;                                       //重心到打击点的距离
    int DILATENUM;                                      //膨胀大小
    int TARGETTHRESH;                                   //目标识别颜色对应通道的阈值
    int ELSETHRESH;                                     //其余通道的阈值
    int COMRETHRESH;                                    //形状符合阈值
    //Rect _roi;
    Img_Time _srcImg;                                        //原始图片
    Mat _processedImg;                                  //二值化图片
    vector<vector<Point2i> > contours;                    //轮廓
    vector<vector<Point2i> > contours_R;                    //轮廓
    vector<Vec4i> hierachy;
    vector<Vec4i> hierachy_R;
    vector<Point> templateContour_swatter;
    vector<Point> templateContour_R;
    vector<Point> newDirections;

    bool _isfund;                                       //是否找到
    bool _isfund_R;
//风车性质变量
    int hitNumber;                                      //击打扇叶的次数
    float fanwidth = 1;                                 //???
    float Lead;                                         //是否进行预测（区分大小幅）
    Point2f _forecastCenter;                            //预测打击点
    Point2f _center;                                    //风车中心
    Point2f _fanCenter;                                 //扇叶重心
    Point2f newDirection;                               //待打击扇叶最远点
    float length;                                       //最远点到重心长度
    Point2f direction;                                  //方向矢量
//运动预测变量
    int buff_type;                                      //小符0大符1
    double pre_sinangle[QUEUE_NUM];
    double FRAMENUMBER;                                 //帧率
    double BULLETSPEED;                                 //子弹初速度
    double BUFFTYPETHRESH;                              //判断大小符的阈值
    double _DISTANCE;
    int _isclockwise;                                  //旋转方向
    Point2f _first_direction;                           //第一帧画面中的方向矢量



    int _framecounter = 0;                              //总共运行帧数，达到一定值后停止计数
    Point2f pre_direction;
    double _pre_angle;


    double start_time;
    double pre_time;
    double prepre_time;
    double max_omega1;
    double max_omega1_time;
    bool max_omega1_find;
    double min_omega;
    bool is_accelerated;
    double refresh_time;

    bool predict_done;


    int pre_angle_head;
    int pre_angle_tail;
    int test_num;
    double min_distance;
    double max_distance;

    vector<Point2d> omegas;
    RotatedRect armor_inside_fan;
    double phi;

//----------------------------
};

}
